package com.unittec.zk.provider.flowable.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.unittec.zk.provider.flowable.service.IFlowDefinitionService;
import com.unittec.zk.provider.log.Log;
import com.unittec.zk.provider.utils.ValidationUtils;
import com.unittec.zk.sdk.flowable.domain.FlowProcDefDto;
import com.unittec.zk.sdk.flowable.request.*;
import com.unittec.zk.sdk.flowable.response.*;
import com.unittec.zk.sdk.root.domain.GatewayRequest;
import com.unittec.zk.sdk.root.domain.Result;
import com.unittec.zk.sdk.root.enums.BizCode;
import com.unittec.zk.sdk.root.enums.BizCodeEnum;
import com.unittec.zk.sdk.root.enums.ErrorEnum;
import com.unittec.zk.sdk.root.internal.exception.BusinessException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 工作流程定义
 * </p>
 *
 * @author XuanXuan
 * @date 2021-04-03
 */
@Api(tags = "流程定义")
@RestController
public class FlowDefinitionController {

    @Autowired
    private IFlowDefinitionService flowDefinitionService;

    @Autowired
    private Log log;


    @RequestMapping(value = "/666001", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "流程定义列表", notes = "流程定义列表",response = FlowProcDefDto.class)
    public Result<Res666001> list(@RequestBody GatewayRequest<Req666001> req) {
        log.debug(req, "list  {} ,param {}", "begin", JSON.toJSONString(req.getContent()));
        BizCodeEnum bizCodeEnum = BizCode.ERROR;
        Res666001 res666001 = null;
        try {
            Req666001 content = req.getContent();
            ValidationUtils.validateEntityStr(content);
            res666001 = new Res666001();
            IPage<FlowProcDefDto> flowDefPageList = flowDefinitionService.list(content.getCurrent().intValue(), content.getSize().intValue());
            res666001.setPage(flowDefPageList);
            bizCodeEnum = BizCode.SUCCESS;
        } catch (Exception e) {
            log.error(req, e.toString(), e);
            if (e instanceof BusinessException) {
                return Result.error(req, e.getMessage());
            } else {
                return Result.error(req, ErrorEnum.QUERY_ERROR.getErrorMessage());
            }
        }
        log.debug(req, "geometryStatisticsByRangeByCondition {}  ", "end");
        if (bizCodeEnum == BizCode.SUCCESS) {
            return Result.success(req, res666001);
        } else {
            return Result.error(req, bizCodeEnum);
        }
    }

    @RequestMapping(value = "/666002", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "导入流程文件", notes = "上传bpmn20的xml文件")
    public Result<Res666002> importFile(@RequestBody GatewayRequest<Req666002> req) {//@RequestParam(required = false) String name,@RequestParam(required = false) String category,MultipartFile file
        log.debug(req, "importFile  {} ,param {}", "begin", JSON.toJSONString(req.getContent()));
        BizCodeEnum bizCodeEnum = BizCode.ERROR;
        Res666002 res666002 = null;
        InputStream in = null;
        try {
            Req666002 content = req.getContent();
            ValidationUtils.validateEntityStr(content);
            res666002 = new Res666002();
            in = content.getFile().getInputStream();
            flowDefinitionService.importFile(content.getName(), content.getCategory(), in);
            bizCodeEnum = BizCode.SUCCESS;
        } catch (Exception e) {
            log.error(req, e.toString(), e);
            if (e instanceof BusinessException) {
                return Result.error(req, e.getMessage());
            } else {
                return Result.error(req, ErrorEnum.QUERY_ERROR.getErrorMessage());
            }
        }
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                log.error(req,"关闭输入流出错", e);
            }
        }
        log.debug(req, "importFile {}  ", "end");
        if (bizCodeEnum == BizCode.SUCCESS) {
            return Result.success(req, res666002);
        } else {
            return Result.error(req, bizCodeEnum);
        }
    }

    @RequestMapping(value = "/666003", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "读取xml文件")
    public Result<Res666003> readXml(@RequestBody GatewayRequest<Req666003> req) {//@ApiParam(value = "流程定义id") @PathVariable(value = "deployId") String deployId
        log.debug(req, "readXml  {} ,param {}", "begin", JSON.toJSONString(req.getContent()));
        BizCodeEnum bizCodeEnum = BizCode.ERROR;
        Res666003 res666003 = null;
        try {
            Req666003 content = req.getContent();
            ValidationUtils.validateEntityStr(content);
            res666003 = new Res666003();
            res666003.setContent(flowDefinitionService.readXml(content.getDeployId()));
            bizCodeEnum = BizCode.SUCCESS;
        } catch (Exception e) {
            log.error(req, e.toString(), e);
            if (e instanceof BusinessException) {
                return Result.error(req, e.getMessage());
            } else {
                return Result.error(req, ErrorEnum.QUERY_ERROR.getErrorMessage());
            }
        }
        log.debug(req, "readXml {}  ", "end");
        if (bizCodeEnum == BizCode.SUCCESS) {
            return Result.success(req, res666003);
        } else {
            return Result.error(req, bizCodeEnum);
        }

    }
    @RequestMapping(value = "/666004", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "读取图片文件")
    public Result<Res666004> readImage(@RequestBody GatewayRequest<Req666004> req) {//@ApiParam(value = "流程定义id") @PathVariable(value = "deployId") String deployId, HttpServletResponse response
        log.debug(req, "readImage  {} ,param {}", "begin", JSON.toJSONString(req.getContent()));
        BizCodeEnum bizCodeEnum = BizCode.ERROR;
        Res666004 res666004 = null;
        OutputStream os = null;
        BufferedImage image = null;
        try {
            res666004 = new Res666004();
            Req666004 content = req.getContent();
            image = ImageIO.read(flowDefinitionService.readImage(content.getDeployId()));
            content.getResponse().setContentType("image/png");
            os = content.getResponse().getOutputStream();
            if (image != null) {
                ImageIO.write(image, "png", os);
            }
            res666004.setImage(image);
            bizCodeEnum = BizCode.SUCCESS;
        } catch (Exception e) {
            log.error(req, e.toString(), e);
            if (e instanceof BusinessException) {
                return Result.error(req, e.getMessage());
            } else {
                return Result.error(req, ErrorEnum.QUERY_ERROR.getErrorMessage());
            }
        } finally {
            try {
                if (os != null) {
                    os.flush();
                    os.close();
                }
            } catch (IOException e) {
//                e.printStackTrace();
                log.error(req, e.toString(), e);
            }
        }
        log.debug(req, "readImage {}  ", "end");
        if (bizCodeEnum == BizCode.SUCCESS) {
            return Result.success(req, res666004);
        } else {
            return Result.error(req, bizCodeEnum);
        }

    }

    @RequestMapping(value = "/666005", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "保存流程设计器内的xml文件")
    public Result<Res666005> saveXml(@RequestBody GatewayRequest<Req666005> req) {//FlowSaveXmlVo vo
        log.debug(req, "saveXml  {} ,param {}", "begin", JSON.toJSONString(req.getContent()));
        BizCodeEnum bizCodeEnum = BizCode.ERROR;
        Res666005 res666005 = null;
        InputStream in = null;
        try {
            res666005 = new Res666005();
            Req666005 content = req.getContent();
            in = new ByteArrayInputStream(content.getXml().getBytes(StandardCharsets.UTF_8));
            flowDefinitionService.importFile(content.getName(), content.getCategory(), in);
            res666005.setContent("导入成功");
        } catch (Exception e) {
            //log.error(null,"导入失败:", e);
            log.error(req, e.toString(), e);
            if (e instanceof BusinessException) {
                return Result.error(req, e.getMessage());
            } else {
                return Result.error(req, ErrorEnum.QUERY_ERROR.getErrorMessage());
            }
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                log.error(req,"关闭输入流出错", e);
            }
        }

        log.debug(req, "saveXml {}  ", "end");
        if (bizCodeEnum == BizCode.SUCCESS) {
            return Result.success(req, res666005);
        } else {
            return Result.error(req, bizCodeEnum);
        }
    }

    @RequestMapping(value = "/666006", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "根据流程定义id启动流程实例")
    public Result<Res666006> start(@RequestBody GatewayRequest<Req666006> req) {//@ApiParam(value = "流程定义id") @PathVariable(value = "procDefId") String procDefId,@ApiParam(value = "变量集合,json对象") @RequestBody Map<String, Object> variables
        log.debug(req, "start  {} ,param {}", "begin", JSON.toJSONString(req.getContent()));
        BizCodeEnum bizCodeEnum = BizCode.ERROR;
        Res666006 res666006 = null;
        try{
            res666006 = new Res666006();
            Req666006 content = req.getContent();
            String rs = flowDefinitionService.startProcessInstanceById(content.getProcDefId(), content.getVariables());
            res666006.setContent(rs);
            if(rs == "流程启动成功"){
                bizCodeEnum = BizCode.SUCCESS;
            }
        }catch (Exception e) {
            //log.error(null,"导入失败:", e);
            log.error(req, e.toString(), e);
            if (e instanceof BusinessException) {
                return Result.error(req, e.getMessage());
            } else {
                return Result.error(req, ErrorEnum.QUERY_ERROR.getErrorMessage());
            }
        }
        log.debug(req, "start {}  ", "end");
        if (bizCodeEnum == BizCode.SUCCESS) {
            return Result.success(req, res666006);
        } else {
            return Result.error(req, bizCodeEnum);
        }
    }

    @RequestMapping(value = "/666007", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "激活或挂起流程定义")
    public Result<Res666007> updateState(@RequestBody GatewayRequest<Req666007> req) {//@ApiParam(value = "1:激活,2:挂起", required = true) @RequestParam Integer state @ApiParam(value = "流程部署ID", required = true) @RequestParam String deployId
        log.debug(req, "updateState  {} ,param {}", "begin", JSON.toJSONString(req.getContent()));
        BizCodeEnum bizCodeEnum = BizCode.ERROR;
        Res666007 res666007 = null;
        try{
            res666007 = new Res666007();
            Req666007 content = req.getContent();
            flowDefinitionService.updateState(content.getState(), content.getDeployId());
            res666007.setContent("流程处理成功！");
        }catch (Exception e) {
            log.error(req, e.toString(), e);
            if (e instanceof BusinessException) {
                return Result.error(req, e.getMessage());
            } else {
                return Result.error(req, ErrorEnum.QUERY_ERROR.getErrorMessage());
            }
        }
        log.debug(req, "updateState {}  ", "end");
        if (bizCodeEnum == BizCode.SUCCESS) {
            return Result.success(req, res666007);
        } else {
            return Result.error(req, bizCodeEnum);
        }
    }

    @RequestMapping(value = "/666008", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "删除流程")
    public Result<Res666008> delete(@RequestBody GatewayRequest<Req666008> req) {//@ApiParam(value = "流程部署ID", required = true) @RequestParam String deployId
        log.debug(req, "delete  {} ,param {}", "begin", JSON.toJSONString(req.getContent()));
        BizCodeEnum bizCodeEnum = BizCode.ERROR;
        Res666008 res666008 = null;
        try{
            res666008 = new Res666008();
            Req666008 content = req.getContent();
            flowDefinitionService.delete(content.getDeployId());
            res666008.setContent("删除流程处理成功！");
        }catch (Exception e) {
            log.error(req, e.toString(), e);
            if (e instanceof BusinessException) {
                return Result.error(req, e.getMessage());
            } else {
                return Result.error(req, ErrorEnum.QUERY_ERROR.getErrorMessage());
            }
        }
        log.debug(req, "delete {}  ", "end");
        if (bizCodeEnum == BizCode.SUCCESS) {
            return Result.success(req, res666008);
        } else {
            return Result.error(req, bizCodeEnum);
        }
    }

    @RequestMapping(value = "/666009", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "指定流程办理人员列表")
    public Result<Res666009> userList(@RequestBody GatewayRequest<Req666009> req) {//SysUser user
        log.debug(req, "userList  {} ,param {}", "begin", JSON.toJSONString(req.getContent()));
        BizCodeEnum bizCodeEnum = BizCode.ERROR;
        Res666009 res666009 = null;
        try{
            res666009 = new Res666009();
            //List<SysUser> list = userService.selectUserList(user);
            res666009.setContent("指定流程办理人员列表处理成功！");
        }catch (Exception e) {
            log.error(req, e.toString(), e);
            if (e instanceof BusinessException) {
                return Result.error(req, e.getMessage());
            } else {
                return Result.error(req, ErrorEnum.QUERY_ERROR.getErrorMessage());
            }
        }
        log.debug(req, "userList {}  ", "end");
        if (bizCodeEnum == BizCode.SUCCESS) {
            return Result.success(req, res666009);
        } else {
            return Result.error(req, bizCodeEnum);
        }
    }

    @RequestMapping(value = "/666010", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "指定流程办理组列表")
    public Result<Res666010> roleList(@RequestBody GatewayRequest<Req666010> req) {//SysRole role
        log.debug(req, "roleList  {} ,param {}", "begin", JSON.toJSONString(req.getContent()));
        BizCodeEnum bizCodeEnum = BizCode.ERROR;
        Res666010 res666010 = null;
        try{
            res666010 = new Res666010();
            //List<SysRole> list = sysRoleService.selectRoleList(role);
            res666010.setContent("指定流程办理组列表处理成功！");
        }catch (Exception e) {
            log.error(req, e.toString(), e);
            if (e instanceof BusinessException) {
                return Result.error(req, e.getMessage());
            } else {
                return Result.error(req, ErrorEnum.QUERY_ERROR.getErrorMessage());
            }
        }
        log.debug(req, "roleList {}  ", "end");
        if (bizCodeEnum == BizCode.SUCCESS) {
            return Result.success(req, res666010);
        } else {
            return Result.error(req, bizCodeEnum);
        }
    }

}